﻿using DeHeng_Mes.Constant;
using DeHeng_Mes.Dao;
using DeHeng_Mes.Dao.PlcDao;
using DeHeng_Mes.Model;
using DeHeng_Mes.Model.Boss;
using DeHeng_Mes.Model.BossModel;
using DeHeng_Mes.Model.ConfigModel;
using DeHeng_Mes.Model.PlcModel;
using DeHeng_Mes.Model.Table;
using DeHeng_Mes.Service.Plc;
using DeHeng_Mes.Thread;
using DeHeng_Mes.Utils;
using FluentFTP;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using yingli_ningbo.Helpers;
using static DeHeng_Mes.Utils.Tools;
using MappingTable = DeHeng_Mes.Utils.MappingTable;
using RichTextBox = System.Windows.Forms.RichTextBox;
using DeHeng_Mes.Mapper;
using SqlSugar;

namespace DeHeng_Mes.Business
{
    public partial class MainForm : Form
    {

        #region 全局成员
        private PlcConnectionManager _plcConnectionManager;
        private FactoryMes factoryMesThread;
        private Polling polling = new Polling();
        private PlcCollectionData plcCollectionData = new PlcCollectionData();
        private CancellationTokenSource cts = new CancellationTokenSource();
        private Andon andon = new Andon();
        private HourOperationToFactoryMes hourOperation = new HourOperationToFactoryMes();
        List<PlcOrderConfigModel> ReadPlcList = PlcOrderConfigModelList.ReadPlcList;
        Dictionary<string, string> AndonModel = AndonConfigModelDic.AndonModel;
        private DataCollector dataCollector = new DataCollector();
        #endregion

        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 私有转换公有
        /// </summary>
        public RichTextBox ProductionLogsText
        {
            get => ProductionLogs;

            set => ProductionLogs = value;
        }

        /// <summary>
        /// 私有转换公有
        /// </summary>
        public RichTextBox DeviceLogsText
        {
            get => DeviceLogs;

            set => DeviceLogs = value;
        }

        /// <summary>
        /// 窗体首次加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryInfo_LoadAsync(object sender, EventArgs e)
        {

            factoryMesThread = new FactoryMes();

            ToolControl(this);

            List<PlcConfigModel> plcList = InitPlcConfig();

            if (plcList != null && plcList.Count > 0)
            {
                _plcConnectionManager = new PlcConnectionManager(plcList);
            }
            if (ReadPlcList != null)
            {
                ProduceLogText("初始化订单模型缓存成功");
            }
            if (AndonModel != null)
            {
                ProduceLogText("初始化安灯语音模型缓存成功");
            }

            // 检测数据库连接
            bool isCollect = MySqlConnect();

            // 检测数据库中是否存在安灯缓存
            andon.AndonInit(isCollect);

            // plc连接线程
            _plcConnectionManager.ConnectToPlc();

            // 安灯播放线程
            _ = Task.Run(() => andon.AndonPlay());

            // 检测线体Plc是否存在未完成订单
            _ = Task.Run(() => factoryMesThread.OrderIsOk());

            // 启动数据轮询采集线程
            //Task.Run(async () => await polling.DataAcquisition());

            // 启动Plc交互采集线程
            _ = plcCollectionData.CollectionTask();

            // 启动产量报工推送线程
            _ = hourOperation.Put();

            // 启动工厂Mes线程监听订单信息
            _ = factoryMesThread.GetOrderDetails();
        }

        #region 自定义方法

        /// <summary>
        /// 初始化PLC配置
        /// </summary>
        private List<PlcConfigModel> InitPlcConfig()
        {
            string[] ips = new string[] { "196.168.0.20", "196.168.0.22", "196.168.0.24", "196.168.0.26", "196.168.0.28", "196.168.0.30"
                                        , "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30"
                                        , "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30", "196.168.0.30" };

            string[] names = new string[] { "leftSpr", "leftGlue", "endWorkSpr", "rightSpr", "rightGlue", "studWeld"
                                          , "SubFDS_1", "SubGlue_1", "SubSpr_1", "SubSpr_2", "SubClinch_1", "SubClinch_2"
                                          , "SubClinch_3", "SubClinch_4", "SubClinch_5", "SubStudWeld_1", "SubStudWeld_2", "SubStudWeld_3" };

            string[] nicks = new string[] { "F2-前围新线左侧Spr工作站", "F2-前围新线左侧涂胶工作站", "F2-前围新线总成合拼工作站", "F2-前围新线右侧Spr工作站", "F2-前围新线右侧涂胶工作站", "F2-前围新线左侧螺柱焊工作站"
                                          , "F2-FDS分站-1", "F2-Glue分站-1", "F2-Spr分站-1", "F2-Spr分站-2", "F2-Clinch分站-1", "F2-Clinch分站-2"
                                          , "F2-Clinch分站-3", "F2-Clinch分站-4", "F2-Clinch分站-5", "F2-StudWeld分站-1", "F2-StudWeld分站-2", "F2-StudWeld分站-3" };
            List<PlcConfigModel> plcConfigs = new List<PlcConfigModel>();
            for (int i = 0; i < ips.Length; i++)
            {
                PlcConfigModel plcConfigModel = new PlcConfigModel();
                plcConfigModel.plc = new Plc(CpuType.S71200, ips[i], 0, 1);
                plcConfigModel.nick = nicks[i];
                plcConfigModel.name = names[i];
                plcConfigModel.cpu = CpuType.S71200;
                plcConfigModel.ip = ips[i];
                plcConfigModel.rack = 0;
                plcConfigModel.slot = 1;
                plcConfigModel.heartBeat = 5000;
                plcConfigModel.retryInterval = 3000;
                plcConfigModel.readInterval = 10000;
                plcConfigModel.isConnected = false;
                plcConfigs.Add(plcConfigModel);
            }
            return plcConfigs;
        }

        #endregion

        private void button21_Click(object sender, EventArgs e)
        {
            // 遍历所有 PLC 配置并找到符合条件的 PLC 实例
            foreach (var plcConfig in PlcConnectionManager.plcContainer)
            {
                if (plcConfig.isConnected)
                {
                    // 获取Count
                    int Count = MappingTable.GetCount(plcConfig.name);

                    if (Count != 0)
                    {
                        for (int i = 1; i <= Count; i++)
                        {
                            plcConfig.plc.Write(DataType.DataBlock, SystemConstant.Order, i.Equals("1") ? 0 : 772 * (i - 1), Tools.ConvertToPlcString("", 0));
                        }
                    }
                    ProduceLogText($"成功清除{plcConfig.nick}中工单缓存");
                }
                else
                {
                    ProduceLogTextError($"{plcConfig.nick}未连接，无法执行缓存清除程序");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string uniqueCode = VirtualCodeGenerator.GenerateVirtualCode();
            Tools.ProduceLogText(uniqueCode);
        }
    }
}
